package org.finesys.common.captcha.config;

import com.anji.captcha.model.common.Const;
import com.anji.captcha.service.CaptchaService;
import com.anji.captcha.service.impl.CaptchaServiceFactory;
import com.anji.captcha.util.ImageUtils;
import lombok.extern.slf4j.Slf4j;
import org.finesys.common.captcha.properties.FineCaptchaProperties;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.util.Base64Utils;
import org.springframework.util.FileCopyUtils;
import org.springframework.util.StringUtils;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

@Slf4j
@Configuration(proxyBeanMethods = false)
public class FineCaptchaServiceAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public CaptchaService captchaService(FineCaptchaProperties fineCaptchaProperties) {
        Properties config = new Properties();
        config.put(Const.CAPTCHA_TYPE, fineCaptchaProperties.getType());
        config.put(Const.CAPTCHA_CACHETYPE, fineCaptchaProperties.getCacheType());
        config.put(Const.CAPTCHA_WATER_MARK, fineCaptchaProperties.getWaterMark());
        config.put(Const.CAPTCHA_WATER_FONT, fineCaptchaProperties.getWaterFont());
        config.put(Const.CAPTCHA_INTERFERENCE_OPTIONS, fineCaptchaProperties.getInterferenceOptions());
        config.put(Const.ORIGINAL_PATH_JIGSAW, fineCaptchaProperties.getJigsaw());
        config.put(Const.ORIGINAL_PATH_PIC_CLICK, fineCaptchaProperties.getPicClick());
        config.put(Const.CAPTCHA_SLIP_OFFSET, fineCaptchaProperties.getSlipOffset());
        config.put(Const.CAPTCHA_CACAHE_MAX_NUMBER, fineCaptchaProperties.getCacheNumber());
        config.put(Const.CAPTCHA_TIMING_CLEAR_SECOND, fineCaptchaProperties.getTimingClear());
        config.put(Const.HISTORY_DATA_CLEAR_ENABLE, fineCaptchaProperties.isHistoryDataClearEnable() ? "1" : "0");
        config.put(Const.REQ_FREQUENCY_LIMIT_ENABLE, fineCaptchaProperties.isReqFrequencyLimitEnable() ? "1" : "0");
        config.put(Const.REQ_CHECK_MINUTE_LIMIT, fineCaptchaProperties.getReqCheckMinuteLimit());
        config.put(Const.REQ_GET_LOCK_LIMIT, fineCaptchaProperties.getReqGetLockLimit());
        config.put(Const.REQ_GET_LOCK_SECONDS, fineCaptchaProperties.getReqGetLockSeconds());
        config.put(Const.REQ_VALIDATE_MINUTE_LIMIT, fineCaptchaProperties.getReqVerifyMinuteLimit());
        config.put(Const.CAPTCHA_AES_STATUS, fineCaptchaProperties.getAesStatus());
        config.put(Const.CAPTCHA_FONT_TYPE, fineCaptchaProperties.getFontType());
        config.put(Const.CAPTCHA_FONT_STYLE, fineCaptchaProperties.getFontStyle());
        config.put(Const.CAPTCHA_FONT_SIZE, fineCaptchaProperties.getFontSize());
        config.put(Const.CAPTCHA_WORD_COUNT, fineCaptchaProperties.getClickWordCount());
        boolean flag = (StringUtils.hasText(fineCaptchaProperties.getJigsaw()) && (fineCaptchaProperties.getJigsaw().startsWith("classpath:") || fineCaptchaProperties.getJigsaw().startsWith("classpath*:")))
                || (StringUtils.hasText(fineCaptchaProperties.getPicClick()) && (fineCaptchaProperties.getPicClick().startsWith("classpath:") || fineCaptchaProperties.getPicClick().startsWith("classpath*:")));
        if (flag) {
            //自定义resource目录下初始化底图
            config.put(Const.CAPTCHA_INIT_ORIGINAL, "true");
            initializeBaseMap(fineCaptchaProperties.getJigsaw(), fineCaptchaProperties.getPicClick());
        }

        return CaptchaServiceFactory.getInstance(config);
    }

    private void initializeBaseMap(String jigsaw, String picClick) {
        ImageUtils.cacheBootImage(getResourcesImages(jigsaw + "/original/*.png"),
                getResourcesImages(jigsaw + "/slidingBlock/*.png"),
                getResourcesImages(picClick + "/*.png"));

    }

    private Map<String, String> getResourcesImages(String path) {
        Map<String, String> imgMap = new HashMap<>();
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();

        try {
            Resource[] resources = resourcePatternResolver.getResources(path);

            for (Resource resource : resources) {
                byte[] bytes = FileCopyUtils.copyToByteArray(resource.getInputStream());
                String contents = Base64Utils.encodeToString(bytes);
                String fileName = resource.getFilename();
                imgMap.put(fileName, contents);
            }
        } catch (IOException e) {

        }
        return imgMap;
    }
}
